package org.xbzheng.restful_study.taglib;

import org.apache.commons.collections.map.HashedMap;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.xbzheng.restful_study.model.Resources;
import org.xbzheng.restful_study.model.User;
import org.xbzheng.restful_study.service.ResourceService;
import org.xbzheng.restful_study.util.ScrumConstant;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Administrator on 2016/11/17.
 */
public class MenuTreeTag extends SimpleTagSupport {
    //菜单id
    private int id = -1;

    @Override
    public void doTag() throws JspException, IOException {
        PageContext context = (PageContext) getJspContext();
        HttpSession session = ((HttpServletRequest) context.getRequest()).getSession();
        User user = (User) session.getAttribute(ScrumConstant.USER);

        ServletContext servletContext = ((HttpServletRequest) context.getRequest()).getServletContext();

        WebApplicationContext webApplicationContext = WebApplicationContextUtils.findWebApplicationContext(servletContext);

        ResourceService service = webApplicationContext.getBean(ResourceService.class);

        List<Resources> resTree = service.findLeftMenu(user.getUsername(), "menu");

        Map<String, Object>  vmData = new HashedMap(1);
        vmData.put("menus", toTree(resTree));

        VelocityEngine engine = webApplicationContext.getBean(VelocityEngine.class);

        String menu = VelocityEngineUtils.mergeTemplateIntoString(engine, "vm/taglib/left_menu.vm", "utf-8", vmData);
        context.getOut().print(menu);
    }

    private List<Resources> toTree(List<Resources> resources){
        if(resources == null) return null;
        final Map<Integer, Resources> map = resources.stream().filter(re -> re.getParent() == null).collect(Collectors.toMap(Resources::getId, (re) -> re));
        resources.stream().filter(re -> re.getParent() != null).forEach(re -> {
            Resources parent = re.getParent();
            if(parent != null){
                int parentId = parent.getId();
                parent = map.get(parentId);
                Set<Resources> children = parent.getChildren();
                if (children == null){
                    children = new HashSet<Resources>();
                }
                children.add(re);
            }
        });
        List<Resources> result = new ArrayList<>();
        for(Map.Entry<Integer, Resources> entry : map.entrySet()){
            result.add(entry.getValue());
        }
        return result;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}
